package definition;

import domain.User;
import org.junit.Test;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Import;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.util.Map;

/**
 * @author jackcfan
 * @date 2021/9/12
 */
@Import(AnnotationBeanDefinitionTest.Config.class)
public class AnnotationBeanDefinitionTest {
    @Test
    public void test(){
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
        // 注册注解配置类
        applicationContext.register(Config.class);
        // 1.通过 @Bean 方式定义
        // 2.通过 @Component 方式
        // 3.通过 @Import 导入

        // 命名Bean注册
        // beanName=oolong-user
        registerUserDenefintion(applicationContext, "oolong-user");

        // 未命名Bean注册
        // beanName=domain.User#0
        registerUserDenefintion(applicationContext);

        applicationContext.refresh();

        Map<String, User> users = applicationContext.getBeansOfType(User.class);
        System.out.println("------------all user bean-----------");
        for(String k : users.keySet()){
            System.out.println("beanName="+k+"\nbean="+users.get(k)+"\n");
        }

        applicationContext.close();
    }

    /**
     * Bean 注册到注册中心
     * */
    public void registerUserDenefintion(BeanDefinitionRegistry registry, String beanName){
        BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(User.class);
        beanDefinitionBuilder.addPropertyValue("id",1)
                .addPropertyValue("name","spring");
        if(StringUtils.hasText(beanName)){
            // 命名 Bean 注册方法
            registry.registerBeanDefinition(beanName, beanDefinitionBuilder.getBeanDefinition());
        }else{
            // 非命名 Bean 注册方法
            BeanDefinitionReaderUtils.registerWithGeneratedName(beanDefinitionBuilder.getBeanDefinition(), registry);
        }
    }

    public void registerUserDenefintion(BeanDefinitionRegistry registry){
        registerUserDenefintion(registry, null);
    }

    @Component
    public static class Config{
        /**
         * 通过 @Bean 注解定义一个 Bean
         * */
        @Bean(name = {"user","aliasUser"})
        public User user(){
            User user = new User();
            user.setId(123L);
            user.setName("spring");
            return user;
        }
    }
}
